home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 38 / Amiga Format CD38 (1999-03-15)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-04].iso / -seriously_amiga- / programming / other / cyberxxxsrc / decoder / txt / decodekpcd.c < prev    next >
C/C++ Source or Header  |  1999-02-08  |  6KB  |  241 lines

  1. /*
  2. sc:c/sc opt txt/DecodeKPCD.c
  3. */
  4.  
  5. #include "Decode.h"
  6. #include "YUV.h"
  7. #include "GlobalVars.h"
  8. #include "Utils.h"
  9.  
  10. struct KPCDData {
  11.   ulong dummy;
  12. };
  13.  
  14. void __regargs YUV221111toRGB(uchar *image, ulong width, ulong height, ulong ix, ulong iy);
  15. void __regargs YUV221111to332(uchar *image, ulong width, ulong height, ulong ix, ulong iy);
  16. void __regargs YUV221111to332Dith(uchar *image, ulong width, ulong height, ulong ix, ulong iy);
  17.  
  18. void __regargs (*yuv221111) (uchar *image, ulong width, ulong height, ulong ix, ulong iy);
  19. ulong kpcdRowIncMult;
  20.  
  21. /* /// "SelectKPCDFuncs()" */
  22. __asm void SelectKPCDFuncs(REG(a0) struct KPCDData *spec,
  23.                            REG(d0) uchar _gray,
  24.                            REG(d1) uchar _dither)
  25. {
  26.   if (_gray) {
  27.     yuv221111=YUV221111to332;
  28.     kpcdRowIncMult=1;
  29.   } else if (_dither) {
  30.     yuv221111=YUV221111to332Dith;
  31.     kpcdRowIncMult=1;
  32.   } else {
  33.     yuv221111=YUV221111toRGB;
  34.     kpcdRowIncMult=4;
  35.   }
  36. }
  37. /* \\\ */
  38.  
  39. /* /// "DecodeKPCD()" */
  40. __asm void DecodeKPCD(REG(a0) uchar *from,
  41.                       REG(a1) uchar *to,
  42.                       REG(d0) ulong width,
  43.                       REG(d1) ulong height,
  44.                       REG(d2) ulong encSize,
  45.                       REG(a2) struct KPCDData *spec)
  46. {
  47.   uchar *dp=from, *ip=to;
  48.   ulong halfWidth=width>>1;
  49.   ulong doubWidth=width<<1;
  50.   ulong srcInc=width*3;
  51.   ulong rowInc=doubWidth;
  52.   struct YUVBuffer yuv;
  53.  
  54.   if (gray) {
  55.     while (height>1) {
  56.       mycopymem((ulong *)dp,(ulong *)ip,doubWidth); // bei Graustufen nur y-Plane kopieren, viel schneller als Kopieren in YUV-Routine
  57.       dp+=srcInc;
  58.       ip+=rowInc;
  59.       height-=2;
  60.     }
  61.     if (height) mycopymem((ulong *)dp,(ulong *)ip,width);
  62.   } else {
  63.     rowInc*=kpcdRowIncMult;
  64.     yuvBuf=&yuv;
  65.     while (height>1) {
  66.       yuv.yBuf=dp;
  67.       yuv.uBuf=dp+doubWidth;
  68.       yuv.vBuf=dp+doubWidth+halfWidth;
  69.       yuv221111(ip,width,2,width,2);
  70.       dp+=srcInc;
  71.       ip+=rowInc;
  72.       height-=2;
  73.     }
  74.     if (height) {
  75.       yuv.yBuf=dp;
  76.       yuv.uBuf=dp+width;
  77.       yuv.vBuf=dp+width+halfWidth;
  78.       yuv221111(ip,width,1,width,1);
  79.     }
  80.   }
  81. }
  82. /* \\\ */
  83.  
  84. /* /// "YUV221111toRGB()" */
  85. void __regargs YUV221111toRGB(uchar *to,
  86.                               ulong width,
  87.                               ulong height,
  88.                               ulong ix,
  89.                               ulong iy)
  90. {
  91.   ulong mx=(width>>1);
  92.   ulong my=height;
  93.   ulong inc=width*4;
  94.   long *ubTab=yuvTab->ubTab;
  95.   long *vrTab=yuvTab->vrTab;
  96.   long *ugTab=yuvTab->ugTab;
  97.   long *vgTab=yuvTab->vgTab;
  98.   long *yTab=yuvTab->yTab;
  99.   uchar *yBuf=yuvBuf->yBuf;
  100.   uchar *uBuf=yuvBuf->uBuf;
  101.   uchar *vBuf=yuvBuf->vBuf;
  102.   ulong flag=0;
  103.  
  104.   while (my--) {
  105.     RGBTriple *ip=(RGBTriple *)to;
  106.     uchar *yp=yBuf;
  107.     uchar *up=uBuf;
  108.     uchar *vp=vBuf;
  109.     ulong x=mx;
  110.     while (x--) {
  111.       ulong iu=*up++;
  112.       ulong iv=*vp++;
  113.       long v2r=vrTab[iv];
  114.       long uv2g=vgTab[iv]+ugTab[iu];
  115.       long u2b=ubTab[iu];
  116.       DecYUVRGB(ip[0],*yp++,v2r,uv2g,u2b);
  117.       DecYUVRGB(ip[1],*yp++,v2r,uv2g,u2b);
  118.       ip+=2;
  119.     }
  120.     to+=inc;
  121.     yBuf+=ix;
  122.     if (flag==0)
  123.       flag=1;
  124.     else {
  125.       flag=0;
  126.       uBuf+=(ix>>1);
  127.       vBuf+=(ix>>1);
  128.     }
  129.   }
  130. }
  131. /* \\\ */
  132.  
  133. /* /// "YUV221111to332()" */
  134. void __regargs YUV221111to332(uchar *to,
  135.                               ulong width,
  136.                               ulong height,
  137.                               ulong ix,
  138.                               ulong iy)
  139. {
  140.   ulong mx=(width>>1);
  141.   ulong my=height;
  142.   long *ubTab=yuvTab->ubTab;
  143.   long *vrTab=yuvTab->vrTab;
  144.   long *ugTab=yuvTab->ugTab;
  145.   long *vgTab=yuvTab->vgTab;
  146.   long *yTab=yuvTab->yTab;
  147.   uchar *yBuf=yuvBuf->yBuf;
  148.   uchar *uBuf=yuvBuf->uBuf;
  149.   uchar *vBuf=yuvBuf->vBuf;
  150.   ulong flag=0;
  151.  
  152.   while (my--) {
  153.     uchar *ip=(uchar *)to;
  154.     uchar *yp=yBuf;
  155.     uchar *up=uBuf;
  156.     uchar *vp=vBuf;
  157.     ulong x=mx;
  158.     while (x--) {
  159.       ulong iu=*up++;
  160.       ulong iv=*vp++;
  161.       long v2r=vrTab[iv];
  162.       long uv2g=vgTab[iv]+ugTab[iu];
  163.       long u2b=ubTab[iu];
  164.  
  165.       DecYUV332(ip,*yp++,v2r,uv2g,u2b);
  166.       DecYUV332(ip,*yp++,v2r,uv2g,u2b);
  167.     }
  168.     to+=width;
  169.     yBuf+=ix;
  170.     if (flag==0)
  171.       flag=1;
  172.     else {
  173.       flag=0;
  174.       uBuf+=(ix>>1);
  175.       vBuf+=(ix>>1);
  176.     }
  177.   }
  178. }
  179. /* \\\ */
  180.  
  181. /* /// "YUV221111to332Dith()" */
  182. void __regargs YUV221111to332Dith(uchar *to,
  183.                                   ulong width,
  184.                                   ulong height,
  185.                                   ulong ix,
  186.                                   ulong iy)
  187. {
  188.   ulong mx=(width>>1);
  189.   ulong my=height;
  190.   long *ubTab=yuvTab->ubTab;
  191.   long *vrTab=yuvTab->vrTab;
  192.   long *ugTab=yuvTab->ugTab;
  193.   long *vgTab=yuvTab->vgTab;
  194.   long *yTab=yuvTab->yTab;
  195.   uchar *yBuf=yuvBuf->yBuf;
  196.   uchar *uBuf=yuvBuf->uBuf;
  197.   uchar *vBuf=yuvBuf->vBuf;
  198.  
  199.   while (my>0) {
  200.     ulong x=mx;
  201.     long re=0, ge=0, be=0;
  202.     uchar *ip0, *ip1;
  203.     uchar *yp0, *yp1;
  204.     uchar *up=uBuf;
  205.     uchar *vp=vBuf;
  206.     ip0=to;
  207.     yp0=yBuf;
  208.     if (my>1) {
  209.       ip1=ip0+width;
  210.       yp1=yp0+width;
  211.       my-=2;
  212.     } else {
  213.       ip1=ip0;
  214.       yp1=yp0;
  215.       my=0;
  216.     }
  217.     while (x--) {
  218.       ulong iu=*up++;
  219.       ulong iv=*vp++;
  220.       long v2r=vrTab[iv];
  221.       long uv2g=vgTab[iv]+ugTab[iu];
  222.       long u2b=ubTab[iu];
  223.  
  224.       DecYUV332Dith(*ip0++,*yp0++,v2r,uv2g,u2b);
  225.       re>>=1; ge>>=1; be>>=1;
  226.       DecYUV332Dith(*ip1++,*yp1++,v2r,uv2g,u2b);
  227.       re>>=1; ge>>=1; be>>=1;
  228.       DecYUV332Dith(*ip1++,*yp1++,v2r,uv2g,u2b);
  229.       re>>=1; ge>>=1; be>>=1;
  230.       DecYUV332Dith(*ip0++,*yp0++,v2r,uv2g,u2b);
  231.       re>>=1; ge>>=1; be>>=1;
  232.     }
  233.     to+=(width<<1);
  234.     yBuf+=(ix<<1);
  235.     uBuf+=(ix>>1);
  236.     vBuf+=(ix>>1);
  237.   }
  238. }
  239. /* \\\ */
  240.  
  241.